%函数说明：多领域交叉结构；Ｍ Ｎ Ｓ Ｃ 的 主 要 思 想 是 ，不 同 的 邻 域 结 构 产 生 不 同 的 搜 索 路 径 ， 
%           因 此 ， 它 可 以 帮 助 探 索 搜 索 空 间 中 的 各 个 区 域 。
% 1.参数life_parent1内的pc、gc均分为组内、组间，而非向量
% 2.LSO_MNSC函数返回的每个life个体已经计算好距离和适应值，因此以后不必再计算（比如幼狮排序选择最优个体），节约时间
function life = LSO_MNSC(Smt,life_parent1,life_parent2,choose,al)
    child_life = life_parent1;
   %% 贴放序列进行MNSC操作，区分组内、组间
    pc1 = life_parent1.lso_mnsc_sequen;
    pc2 = life_parent2.lso_mnsc_sequen;
    life_parent1.alpha = reshape(life_parent1.alpha,[1,Smt.R*Smt.head_num]);
    life_parent2.alpha = reshape(life_parent2.alpha,[1,Smt.R*Smt.head_num]);
    
    life_parent1.zeta = reshape(life_parent1.zeta,[1,Smt.R*Smt.head_num]);
    life_parent2.zeta = reshape(life_parent2.zeta,[1,Smt.R*Smt.head_num]);
    fc1 = life_parent1.fc;
    fc2 = life_parent2.fc;
    [rol,col] = size(life_parent1.pc);
    %如果元件序列格式分组间、组内，转换成向量以便进行MNSC操作
%     if rol > 1
%         pc1 = reshape(pc1,[1,rol*col]);
%         pc2 = reshape(pc2,[1,rol*col]);
%     end
    % 为了保证mnsc操作不会出错，需要把奇数个元件的末尾补零给去掉
    %% mnsc只对组间顺序操作，不改变组内顺序
    switch choose
        case 1 %部分匹配法（PMX）
            child_life.alpha = LSO_MNSC_PMX(life_parent1.alpha,life_parent2.alpha);
            child_life.fc = LSO_MNSC_PMX(fc1,fc2);
         case 2 % 次序交叉法（OX），等于《基于协同进化的混合智能优化算法在SMT中的应用研究_张雪》P41喂料器使用的领域交叉算子
             child_life.lso_mnsc_sequen = LSO_MNSC_OX(pc1,pc2);
%             child_life.fc = LSO_MNSC_OX(fc1,fc2);
%         case 3 %基于位置的交叉法（PBX）
%            child_life.lso_mnsc_sequen = LSO_MNSC_PBX(pc1,pc2);
%             child_life.fc = LSO_MNSC_PBX(fc1,fc2);
%         case 4 %基于次序的交叉法（OBX）
%             child_life.lso_mnsc_sequen = LSO_MNSC_OBX(pc1,pc2);
%             child_life.fc = LSO_MNSC_OBX(fc1,fc2);
        otherwise  
    end
    %% 解码mnsc,注意返回的是向量
    child_life.alpha = Inter_Group_Decode(child_life.alpha,child_life.lso_mnsc_sequen);
    %% 
    %% 解码mnsc之后原本最后带0的一组可能会移动到另一组，因此要删掉0
    child_life.alpha(find(child_life.pc == 0)) = [];%删掉0
    %% 再在最后一组添上0（Dis_Sum函数内部会处理0的情况）
    child_life.alpha(Smt.nC+1:rol*col) = 0;
    %% 将吸头元件分配重新分组内组间
    child_life.alpha = reshape(child_life.alpha,[Smt.R,Smt.head_num]);
    life_parent1.alpha = reshape(life_parent1.alpha,[Smt.R,Smt.head_num]);
    life_parent2.alpha = reshape(life_parent2.alpha,[Smt.R,Smt.head_num]);
    child_life.zeta = child_life.alpha;
    %% 将贴放元件重新分配为组内组间
    child_life.zeta = reshape(child_life.zeta,[Smt.R,Smt.head_num]);
    life_parent1.zeta = reshape(life_parent1.zeta,[Smt.R,Smt.head_num]);
    life_parent2.zeta = reshape(life_parent2.zeta,[Smt.R,Smt.head_num]);
%     %% 计算生成的个体与父代的相似度(这里只比较了一个父代)
%     same_num = 1;
%     dif_num = 1;
%     for i = 1:length(life_parent1.pc)
%         if child_life.pc(i) == life_parent1.pc(i)
%             same_num = same_num+1;
%         else
%             dif_num = dif_num+1;
%         end
%     end
%     dist = (same_num-dif_num)/same_num;%相似度越小，种群多样性越大
    %% 计算父代的适应值
    disp('父代距离')
    life_parent1.dis_sum = Dis_Sum(Smt,life_parent1.alpha,life_parent1.zeta,life_parent1.lamb);
    parent_dis = life_parent1.dis_sum ;
    life_parent1.fitness = 10000/life_parent1.dis_sum;%以距离的倒数作为适应值，因计算的距离数值较大所以倒数值放大一千倍
    %% 不能再使用Count_Fit，因为MNSC直接处理元件，而不是pc、gc、fc的编码
%     [life_parent1.fitness,life_parent1.dis_sum] = Count_Fit(Smt,life_parent1);
    %% 计算MNSC生成的子代适应值
    disp('子代距离')
    child_life.dis_sum = Dis_Sum(Smt,child_life.alpha,child_life.zeta,child_life.lamb);
    child_dis = child_life.dis_sum
    child_life.fitness = 10000/child_life.dis_sum;%以距离的倒数作为适应值，因计算的距离数值较大所以倒数值放大一千倍
    % 有个问题，MNSC操作没有同时处理pc、gc，gc组内顺序如何与pc不同？难道又使用任选pc组内两个位置互换？答：目前让gc所有组组内两个元件随机互换
    %%  考虑个体相似度的适应值比较
    %考虑父代与子代个体相似度的适应度计算，相似度越小()，越容易被保留
    %dist的范围约是-length(pc)~1,超过一百个元件序号相同相似度约为0.55，120个元件相同约为0.8
    %原始适应值（扩大一万倍）范围约为0.24~0.8
    if (child_life.fitness)>life_parent1.fitness
        life = child_life;%适应度大的被保留
         disp(['MNSC成功保留适应值大的子代',num2str(life.fitness)])
         disp(['MNSC成功保留距离短的子代',num2str(life.dis_sum)])
    else
        life = life_parent1;
    end
end
    

                
                
                